from flask import Flask, jsonify
from flask_cors import CORS

from applications import manage
from applications.extensions import db
from applications.extensions import jwt
from applications.extensions import migrate, celery

from applications import api_common
from applications import system
from applications import api_crud


def create_app(testing=False):
    """Application factory, used to create application"""
    app = Flask("faster_api")

    CORS(app, supports_credentials=True)
    # app = Flask("faster_api", template_folder="www", static_folder='www', static_url_path='')

    app.config.from_object("applications.config")

    # app.wsgi_app = WhiteNoise(app.wsgi_app, root="www/dist/")
    configure_extensions(app)
    configure_cli(app)
    register_blueprints(app)
    init_celery(app)

    # 全局异常处理
    # @app.errorhandler(Exception)
    # def error_handler(e):
    #     import traceback
    #     print(traceback.format_exc(e))
    #     data = {
    #         "code": 500,
    #         "msg": "服务器内部错误"
    #     }
    #     return jsonify(data)

    return app


def configure_extensions(app):
    """Configure flask extensions"""
    db.init_app(app)
    jwt.init_app(app)
    migrate.init_app(app, db)
    # admin_loggin_middleware(app)


def configure_cli(app):
    """Configure Flask 2.0's cli for easy entity management"""
    app.cli.add_command(manage.init)


def register_blueprints(app):
    """Register all blueprints for application"""
    # app.register_blueprint(auth.views.blueprint)
    app.register_blueprint(api_crud.views.blueprint)
    app.register_blueprint(api_common.views.blueprint)
    app.register_blueprint(system.routers.blueprint)
    # app.register_blueprint(system_api.views_mall.blueprint)


def init_celery(app=None):
    app = app or create_app()
    celery.conf.update(app.config.get("CELERY", {}))

    class ContextTask(celery.Task):
        """Make celery tasks work with Flask app context"""

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return self.run(*args, **kwargs)

    celery.Task = ContextTask
    return celery
